package com.google.code.seditor.gui;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import com.google.code.seditor.R;
import com.google.code.seditor.db.DaoFactory;
import com.google.code.seditor.db.FileDao;
import com.google.code.seditor.utils.Constants;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;

public class MainEditor extends Activity {

	private EditText mBodyText;
	private String encoding="utf-8";
    private Long rowId;
    private String path;
    
    private static final int SAVE_ID = Menu.FIRST;
	private static final int SAVE_AS_ID = Menu.FIRST + 1;
	private static final int ENCODING_ID = Menu.FIRST + 2;
    
    @Override
	public boolean onCreateOptionsMenu(Menu menu) {
		boolean result = super.onCreateOptionsMenu(menu);
		menu.add(0, SAVE_ID, 0, R.string.menu_save);
		menu.add(0, SAVE_AS_ID, 0, R.string.menu_saveas);
		menu.add(0, ENCODING_ID, 0, R.string.menu_encoding);
		return result;
	}
    
    @Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case SAVE_ID:
			saveAll();
			return true;
		case SAVE_AS_ID:
			this.saveAsAction();
			return true;
		case ENCODING_ID:
			this.populateFields();
			return true;
		}

		return super.onOptionsItemSelected(item);
	}
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.editor);
		
		this.initStartParam(savedInstanceState);
		this.mBodyText=(EditText) this.findViewById(R.id.editText1);
		
		populateFields();
		
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		DaoFactory.close(this);
	}

	private void initStartParam(Bundle savedInstanceState){
		this.rowId = this.getParamByKey(savedInstanceState, Constants.PARAM_ROWID);
		this.path = this.getParamByKey(savedInstanceState, Constants.PARAM_PATH);	
		
	}
	
	@SuppressWarnings("unchecked")
	private <T> T getParamByKey(Bundle savedInstanceState,String key){
		
		T result = (savedInstanceState == null) ? null :
            (T) savedInstanceState.getSerializable(key);
		if (result == null) {
			Bundle extras = getIntent().getExtras();
			result = extras != null ? (T)extras.get(key)
									: null;
		}
		
		return result;
	}
	
	private void populateFields() {
		if(rowId==null){
			mBodyText.setText("");
		}else{
			mBodyText.setText(this.getFileContent(this.path, this.encoding));
		}
    }
	
	private String getFileContent(String path,String encoding){
		StringBuilder sb=new StringBuilder();
		
		BufferedInputStream fis =null;
		BufferedReader reader = null;
		try {
			fis = new BufferedInputStream(new FileInputStream(path));
			reader = new BufferedReader(new InputStreamReader(fis,encoding),10240);
			String line="";
			while((line=reader.readLine())!=null){
				sb.append(line);
			}
		} catch (Exception e) {
			Log.w("MainEditor", e);
		} finally {
			try{
			reader.close();
			fis.close();
			} catch (Exception ex){
				Log.w("MainEditor", ex);
			}
		}
		
		
		return sb.toString();
	}
	
	private void saveAll(){
		try {
			if (this.rowId == null) {

				String fileName = "default";
				
				//display filename input dialog
				fileName=this.showFileNameDlg();
				if(fileName==null){
					return ;
				}				
				
				File savedFile=this.createFile(fileName, encoding);
				
				//insert record to DB
				FileDao fileDao=(FileDao)DaoFactory.getDao(MainEditor.class, this);
				fileDao.createNote(fileName, savedFile.getAbsolutePath());

			} else {
				File file=new File(this.path);
				this.saveToFile(file);

			}
		} catch (Exception e) {
			Log.w("MainEditor", e);
		}
	}
	
	private String showFileNameDlg(){
		String result=null;
		final EditText txtInput=new EditText(this);		
		(new AlertDialog.Builder(this))
		.setTitle("file name")
		.setView(txtInput)
		.setPositiveButton("OK", new OnClickListener(){
			 public void onClick(DialogInterface dialog, int which){
				 if("".equals(txtInput.getText().toString())){
					 return;
				 }
				 
				 //result=txtInput.getText().toString();
				 dialog.dismiss();
			 }
		})
		.setNegativeButton("Cancel", new OnClickListener(){
			 public void onClick(DialogInterface dialog, int which){
				 dialog.cancel();
			 }
		})
		.show();
		
		result=txtInput.getText().toString();
		return result;
	}
	
	private void saveAsAction() {
		try {
			String fileName = "default";

			// display filename input dialog
			fileName = this.showFileNameDlg();
			if (fileName == null) {
				return;
			}

			File savedFile = this.createFile(fileName, encoding);

			// insert record to DB
			FileDao fileDao = (FileDao) DaoFactory.getDao(MainEditor.class, this);
			if (this.rowId == null) {
				fileDao.createNote(fileName, savedFile.getAbsolutePath());
			} else {
				fileDao.updateNote(this.rowId, fileName,
						savedFile.getAbsolutePath());
			}

		} catch (Exception e) {
			Log.w("MainEditor", e);
		}

	}
	
	private File createFile(String fileName,String encoding) throws Exception{
		
		File rootPath=Environment.getExternalStorageDirectory();
		
		File privateDir=new File(rootPath,Constants.SAVE_DIR);
		
		if(!privateDir.exists()||!privateDir.isDirectory()){
			privateDir.mkdir();
		}
		
		File saveFile=new File(privateDir,fileName);
		
		if(saveFile.exists()){
			return null;
		}
		
		saveFile.createNewFile();
		
		this.saveToFile(saveFile);
		
		return saveFile;
	}
	
	private void saveToFile(File file) throws Exception{
		BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(file));
		BufferedWriter bw= new BufferedWriter(new OutputStreamWriter(bos, encoding));
		bw.write(this.mBodyText.getText().toString());
		bw.flush();
		bw.close();
	}

}
